package com.tianji.remark.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.common.utils.UserContext;
import com.tianji.remark.constants.RedisConstants;
import com.tianji.remark.domin.dto.LikeRecordFormDTO;
import com.tianji.remark.domin.po.LikedRecord;
import com.tianji.remark.mapper.LikedRecordMapper;
import com.tianji.remark.service.ILikedRecordService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

/**
 * <p>
 * 点赞记录表 服务实现类
 * </p>
 *
 * @author author
 * @since 2023-11-02
 */
@Service
@RequiredArgsConstructor
@Slf4j
@Transactional
public class LikedRecordServiceImpl extends ServiceImpl<LikedRecordMapper, LikedRecord> implements ILikedRecordService {

    private final RedisTemplate<String, String> redisTemplate;

    @Override
    public void likedRecord(LikeRecordFormDTO dto) {
        Long userId = UserContext.getUser();
        boolean userLikes = dto.getLiked();

        // 点赞与取消点赞逻辑合并处理
        if (!processLikeOrUnlike(userLikes, userId, dto)) {
            return;
        }
        // 3.如果执行成功，统计点赞总数
        Long likedTimes = redisTemplate.opsForSet().size(RedisConstants.LIKE_BIZ_KEY_PREFIX + dto.getBizId());

        if (likedTimes == null) {
            return;
        }
        // 4.缓存点总数到Redis
        redisTemplate.opsForZSet().add(RedisConstants.LIKES_TIMES_KEY_PREFIX + dto.getBizType(), dto.getBizId().toString(), likedTimes);
    }


    private boolean processLikeOrUnlike(boolean userLikes, Long userId, LikeRecordFormDTO dto) {
        if (userLikes) {
            return saveLikedRecord(userId, dto);
        } else {
            return removeLikedRecord(userId, dto);
        }
    }

    private boolean saveLikedRecord(Long userId, LikeRecordFormDTO dto) {

        String key = RedisConstants.LIKE_BIZ_KEY_PREFIX + dto.getBizId();

        Long add = redisTemplate.opsForSet().add(key, userId.toString());

        return add != null && add > 0;
    }

    private boolean removeLikedRecord(Long userId, LikeRecordFormDTO dto) {

        String key = RedisConstants.LIKE_BIZ_KEY_PREFIX + dto.getBizId();

        Long remove = redisTemplate.opsForSet().remove(key, userId.toString());
        return remove != null && remove > 0;
    }

    @Override
    public Set<Long> getLikesStatusByBizIds(List<Long> bizIds) {

        //获取用户id
        Long userId = UserContext.getUser();

        //批量查询rides
        List<Object> redisResult = redisTemplate.executePipelined((RedisCallback<Boolean>) connection -> {

            StringRedisTemplate stringRedisTemplate = (StringRedisTemplate) connection;
            for (Long bizId : bizIds) {

                String key = RedisConstants.LIKE_BIZ_KEY_PREFIX + bizId;
                stringRedisTemplate.opsForSet().isMember(key, userId.toString());
            }
            return null;
        });
        return IntStream.range(0, bizIds.size()).filter(i -> (boolean) redisResult.get(i)).mapToObj(bizIds::get).collect(Collectors.toSet());
    }

}
